﻿using System;
using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace Dynamic.Data.Model.Query
{
    [DataContract]
    [XmlInclude(typeof(ConditionExpression))]
    public sealed class FilterExpression
    {
        private List<ConditionExpression> _conditions = new List<ConditionExpression>();
        private LogicalOperator _filterOperator = LogicalOperator.And;
        private List<FilterExpression> _filters = new List<FilterExpression>();

        public void Accept(IQueryVisitor visitor)
        {
            visitor.Visit(this);
        }

        public void AddCondition(ConditionExpression condition)
        {
            this._conditions.Add(condition);
        }

        public void AddCondition(string entityName, string attributeName, ConditionOperator conditionOperator)
        {
            this._conditions.Add(new ConditionExpression(entityName, attributeName, conditionOperator));
        }

        public void AddCondition(string entityName, string attributeName, ConditionOperator conditionOperator, Array values)
        {
            this._conditions.Add(new ConditionExpression(entityName, attributeName, conditionOperator, values));
        }

        public void AddCondition(string entityName, string attributeName, ConditionOperator conditionOperator, object value)
        {
            this._conditions.Add(new ConditionExpression(entityName, attributeName, conditionOperator, value));
        }

        public void AddFilter(FilterExpression childFilter)
        {
            if (childFilter != null)
            {
                this._filters.Add(childFilter);
            }
        }

        public FilterExpression AddFilter(LogicalOperator lo)
        {
            FilterExpression expression = new FilterExpression {
                FilterOperator = lo
            };
            this._filters.Add(expression);
            return expression;
        }

        [DataMember]
        [XmlArray, XmlArrayItem(ElementName="Condition", IsNullable=false, Type=typeof(ConditionExpression))]
        public List<ConditionExpression> Conditions
        {
            get
            {
                return this._conditions;
            }
            set
            {
                this._conditions = value;
            }
        }

        [DataMember]
        public LogicalOperator FilterOperator
        {
            get
            {
                return this._filterOperator;
            }
            set
            {
                this._filterOperator = value;
            }
        }


        [DataMember]
        [XmlArrayItem(ElementName="Filter", IsNullable=false, Type=typeof(FilterExpression)), XmlArray]
        public List<FilterExpression> Filters
        {
            get
            {
                return this._filters;
            }
            set
            {
                this._filters = value;
            }
        }
    }
}

